package com.nf.mvc.mappings;

import com.nf.mvc.HandlerMapping;
import com.nf.mvc.MvcContest;
import com.nf.mvc.handler.HandlerInfo;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class RequestMappingHandlerMapping implements HandlerMapping {
    private Map<String, HandlerInfo> handlers=new HashMap<>();
    public RequestMappingHandlerMapping(){
        resolveHandlers();
    }

    protected void resolveHandlers(){
        List<Class<?>> classList = MvcContest.getMvcContest().getAllScanedClasses();

        for (Class<?> clz : classList) {
            String urlInClass=getUrl(clz);
            Method[] methods = clz.getDeclaredMethods();
            for (Method method : methods) {
                if (method.isAnnotationPresent(RequestMapping.class)){
                    HandlerInfo handlerInfo=new HandlerInfo(method);
                    String urlInMethod = getUrl(method);
                    String url=urlInClass+urlInMethod;
                    addHandler(url,handlerInfo);
                }
            }
        }
    }
    protected void addHandler(String url,HandlerInfo handlerInfo){
        if (handlers.get(url)!=null){
            throw new IllegalStateException("不能有多个处理者对应同一个url");
        }
        this.handlers.put(url, handlerInfo);
    }

    @Override
    public Object getHandler(HttpServletRequest request) throws Exception {
        String requestUrl = getRequestUrl(request);
        return handlers.get(requestUrl);
    }

    private String getUrl(AnnotatedElement element){
        return element.isAnnotationPresent(RequestMapping.class)?
                element.getDeclaredAnnotation(RequestMapping.class).value().toLowerCase():"";
    }
}
